@@ -3,14 +3,14 @@  | 
            ||
| 3 | 3 | 
                from django.contrib import admin  | 
            
| 4 | 4 | 
                from django.contrib.auth.hashers import make_password  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                -from account.models import LensmanInfo  | 
            |
| 6 | 
                +from account.models import LensmanInfo, LensmanLoginLogInfo, UserInfo, UserLoginLogInfo  | 
            |
| 7 | 7 | 
                 | 
            
| 8 | 8 | 
                from utils.uuid_utils import curtailUUID  | 
            
| 9 | 9 | 
                 | 
            
| 10 | 10 | 
                 | 
            
| 11 | 11 | 
                class LensmanInfoAdmin(admin.ModelAdmin):  | 
            
| 12 | 12 | 
                     readonly_fields = ('lensman_id', 'encryption', )
               | 
            
| 13 | 
                -    list_display = ('lensman_id', 'name', 'sex', 'phone', 'location', 'proportion', 'status', 'created_at', 'updated_at')
               | 
            |
| 13 | 
                +    list_display = ('lensman_id', 'username', 'name', 'sex', 'phone', 'location', 'proportion', 'status', 'created_at', 'updated_at')
               | 
            |
| 14 | 14 | 
                     search_fields = ('name', 'phone', 'location')
               | 
            
| 15 | 15 | 
                     list_filter = ('sex', 'status')
               | 
            
| 16 | 16 | 
                 | 
            
                @@ -23,4 +23,22 @@ class LensmanInfoAdmin(admin.ModelAdmin):  | 
            ||
| 23 | 23 | 
                obj.save()  | 
            
| 24 | 24 | 
                 | 
            
| 25 | 25 | 
                 | 
            
| 26 | 
                +class LensmanLoginLogInfoAdmin(admin.ModelAdmin):  | 
            |
| 27 | 
                +    list_display = ('lensman_id', 'login_ip', 'login_result', 'status', 'created_at', 'updated_at')
               | 
            |
| 28 | 
                +  | 
            |
| 29 | 
                +  | 
            |
| 30 | 
                +class UserInfoAdmin(admin.ModelAdmin):  | 
            |
| 31 | 
                +    readonly_fields = ('user_id', )
               | 
            |
| 32 | 
                +    list_display = ('user_id', 'username', 'name', 'sex', 'phone', 'location', 'user_status', 'status', 'created_at', 'updated_at')
               | 
            |
| 33 | 
                +    search_fields = ('name', 'phone', 'location')
               | 
            |
| 34 | 
                +    list_filter = ('sex', 'status', 'user_status')
               | 
            |
| 35 | 
                +  | 
            |
| 36 | 
                +  | 
            |
| 37 | 
                +class UserLoginLogInfoAdmin(admin.ModelAdmin):  | 
            |
| 38 | 
                +    list_display = ('user_id', 'login_ip', 'login_result', 'status', 'created_at', 'updated_at')
               | 
            |
| 39 | 
                +  | 
            |
| 40 | 
                +  | 
            |
| 26 | 41 | 
                admin.site.register(LensmanInfo, LensmanInfoAdmin)  | 
            
| 42 | 
                +admin.site.register(UserInfo, UserInfoAdmin)  | 
            |
| 43 | 
                +admin.site.register(LensmanLoginLogInfo, LensmanLoginLogInfoAdmin)  | 
            |
| 44 | 
                +admin.site.register(UserLoginLogInfo, UserLoginLogInfoAdmin)  | 
            
                @@ -0,0 +1,85 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +from __future__ import unicode_literals  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +from django.db import models, migrations  | 
            |
| 5 | 
                +  | 
            |
| 6 | 
                +  | 
            |
| 7 | 
                +class Migration(migrations.Migration):  | 
            |
| 8 | 
                +  | 
            |
| 9 | 
                + dependencies = [  | 
            |
| 10 | 
                +        ('account', '0004_auto_20151207_1811'),
               | 
            |
| 11 | 
                + ]  | 
            |
| 12 | 
                +  | 
            |
| 13 | 
                + operations = [  | 
            |
| 14 | 
                + migrations.CreateModel(  | 
            |
| 15 | 
                + name='LensmanLoginLogInfo',  | 
            |
| 16 | 
                + fields=[  | 
            |
| 17 | 
                +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
               | 
            |
| 18 | 
                +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
               | 
            |
| 19 | 
                +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
               | 
            |
| 20 | 
                +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
               | 
            |
| 21 | 
                +                ('lensman_id', models.CharField(max_length=255, blank=True, help_text='\u6444\u5f71\u5e08\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='lensman_id', db_index=True)),
               | 
            |
| 22 | 
                +                ('login_ip', models.CharField(help_text='\u767b\u5f55IP', max_length=255, null=True, verbose_name='login_ip', blank=True)),
               | 
            |
| 23 | 
                +                ('login_result', models.IntegerField(default=0, verbose_name='login_result', choices=[(0, '\u767b\u5f55\u6210\u529f'), (1, '\u5bc6\u7801\u9519\u8bef'), (2, '\u5176\u4ed6')])),
               | 
            |
| 24 | 
                + ],  | 
            |
| 25 | 
                +            options={
               | 
            |
| 26 | 
                + 'verbose_name': 'lensmanloginloginfo',  | 
            |
| 27 | 
                + 'verbose_name_plural': 'lensmanloginloginfo',  | 
            |
| 28 | 
                + },  | 
            |
| 29 | 
                + ),  | 
            |
| 30 | 
                + migrations.CreateModel(  | 
            |
| 31 | 
                + name='UserInfo',  | 
            |
| 32 | 
                + fields=[  | 
            |
| 33 | 
                +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
               | 
            |
| 34 | 
                +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
               | 
            |
| 35 | 
                +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
               | 
            |
| 36 | 
                +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
               | 
            |
| 37 | 
                +                ('user_id', models.CharField(null=True, max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='user_id', db_index=True)),
               | 
            |
| 38 | 
                +                ('username', models.CharField(null=True, max_length=255, blank=True, help_text='\u7528\u6237\u7528\u6237\u540d', unique=True, verbose_name='username', db_index=True)),
               | 
            |
| 39 | 
                +                ('password', models.CharField(help_text='\u7528\u6237\u5bc6\u7801', max_length=255, null=True, verbose_name='password', blank=True)),
               | 
            |
| 40 | 
                +                ('name', models.CharField(help_text='\u7528\u6237\u59d3\u540d', max_length=255, null=True, verbose_name='name', blank=True)),
               | 
            |
| 41 | 
                +                ('sex', models.IntegerField(default=0, help_text='\u7528\u6237\u6027\u522b', verbose_name='sex', choices=[(0, '\u7537'), (1, '\u5973')])),
               | 
            |
| 42 | 
                +                ('phone', models.CharField(null=True, max_length=255, blank=True, help_text='\u7528\u6237\u7535\u8bdd', unique=True, verbose_name='phone', db_index=True)),
               | 
            |
| 43 | 
                +                ('location', models.CharField(help_text='\u7528\u6237\u5730\u5740', max_length=255, null=True, verbose_name='location', blank=True)),
               | 
            |
| 44 | 
                +                ('user_status', models.IntegerField(default=0, verbose_name='user_status', choices=[(0, '\u672a\u9a8c\u8bc1'), (1, '\u5df2\u6fc0\u6d3b'), (2, '\u5df2\u7981\u7528'), (3, '\u5df2\u5220\u9664')])),
               | 
            |
| 45 | 
                +                ('signup_ip', models.CharField(help_text='\u6ce8\u518cIP', max_length=255, null=True, verbose_name='signup_ip', blank=True)),
               | 
            |
| 46 | 
                +                ('login_ip', models.CharField(help_text='\u767b\u5f55IP', max_length=255, null=True, verbose_name='login_ip', blank=True)),
               | 
            |
| 47 | 
                +                ('login_at', models.DateTimeField(help_text='\u767b\u5f55\u65f6\u95f4', null=True, verbose_name='login_at', blank=True)),
               | 
            |
| 48 | 
                + ],  | 
            |
| 49 | 
                +            options={
               | 
            |
| 50 | 
                + 'verbose_name': 'userinfo',  | 
            |
| 51 | 
                + 'verbose_name_plural': 'userinfo',  | 
            |
| 52 | 
                + },  | 
            |
| 53 | 
                + ),  | 
            |
| 54 | 
                + migrations.CreateModel(  | 
            |
| 55 | 
                + name='UserLoginLogInfo',  | 
            |
| 56 | 
                + fields=[  | 
            |
| 57 | 
                +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
               | 
            |
| 58 | 
                +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', verbose_name='status')),
               | 
            |
| 59 | 
                +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)),
               | 
            |
| 60 | 
                +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)),
               | 
            |
| 61 | 
                +                ('user_id', models.CharField(max_length=255, blank=True, help_text='\u7528\u6237\u552f\u4e00\u6807\u8bc6', null=True, verbose_name='user_id', db_index=True)),
               | 
            |
| 62 | 
                +                ('login_ip', models.CharField(help_text='\u767b\u5f55IP', max_length=255, null=True, verbose_name='login_ip', blank=True)),
               | 
            |
| 63 | 
                +                ('login_result', models.IntegerField(default=0, verbose_name='login_result', choices=[(0, '\u767b\u5f55\u6210\u529f'), (1, '\u5bc6\u7801\u9519\u8bef'), (2, '\u5176\u4ed6')])),
               | 
            |
| 64 | 
                + ],  | 
            |
| 65 | 
                +            options={
               | 
            |
| 66 | 
                + 'verbose_name': 'userloginloginfo',  | 
            |
| 67 | 
                + 'verbose_name_plural': 'userloginloginfo',  | 
            |
| 68 | 
                + },  | 
            |
| 69 | 
                + ),  | 
            |
| 70 | 
                + migrations.AddField(  | 
            |
| 71 | 
                + model_name='lensmaninfo',  | 
            |
| 72 | 
                + name='login_at',  | 
            |
| 73 | 
                + field=models.DateTimeField(help_text='\u767b\u5f55\u65f6\u95f4', null=True, verbose_name='login_at', blank=True),  | 
            |
| 74 | 
                + ),  | 
            |
| 75 | 
                + migrations.AddField(  | 
            |
| 76 | 
                + model_name='lensmaninfo',  | 
            |
| 77 | 
                + name='login_ip',  | 
            |
| 78 | 
                + field=models.CharField(help_text='\u767b\u5f55IP', max_length=255, null=True, verbose_name='login_ip', blank=True),  | 
            |
| 79 | 
                + ),  | 
            |
| 80 | 
                + migrations.AddField(  | 
            |
| 81 | 
                + model_name='lensmaninfo',  | 
            |
| 82 | 
                + name='signup_ip',  | 
            |
| 83 | 
                + field=models.CharField(help_text='\u6ce8\u518cIP', max_length=255, null=True, verbose_name='signup_ip', blank=True),  | 
            |
| 84 | 
                + ),  | 
            |
| 85 | 
                + ]  | 
            
                @@ -28,9 +28,112 @@ class LensmanInfo(CreateUpdateMixin):  | 
            ||
| 28 | 28 | 
                 | 
            
| 29 | 29 | 
                proportion = models.FloatField(_(u'proportion'), default=1.0, help_text=u'摄影师分成比例(0.0 ~ 1.0)')  | 
            
| 30 | 30 | 
                 | 
            
| 31 | 
                + signup_ip = models.CharField(_(u'signup_ip'), max_length=255, blank=True, null=True, help_text=_(u'注册IP'))  | 
            |
| 32 | 
                + login_ip = models.CharField(_(u'login_ip'), max_length=255, blank=True, null=True, help_text=_(u'登录IP'))  | 
            |
| 33 | 
                + login_at = models.DateTimeField(_(u'login_at'), blank=True, null=True, help_text=_(u'登录时间'))  | 
            |
| 34 | 
                +  | 
            |
| 31 | 35 | 
                class Meta:  | 
            
| 32 | 36 | 
                verbose_name = _(u'lensmaninfo')  | 
            
| 33 | 37 | 
                verbose_name_plural = _(u'lensmaninfo')  | 
            
| 34 | 38 | 
                 | 
            
| 35 | 39 | 
                def __unicode__(self):  | 
            
| 36 | 40 | 
                return unicode(self.pk)  | 
            
| 41 | 
                +  | 
            |
| 42 | 
                +  | 
            |
| 43 | 
                +class LensmanLoginLogInfo(CreateUpdateMixin):  | 
            |
| 44 | 
                + SUCCESS = 0  | 
            |
| 45 | 
                + PWD_ERROR = 1  | 
            |
| 46 | 
                + OTHER = 2  | 
            |
| 47 | 
                +  | 
            |
| 48 | 
                + LOGIN_RESULT = (  | 
            |
| 49 | 
                + (SUCCESS, u'登录成功'),  | 
            |
| 50 | 
                + (PWD_ERROR, u'密码错误'),  | 
            |
| 51 | 
                + (OTHER, u'其他'),  | 
            |
| 52 | 
                + )  | 
            |
| 53 | 
                +  | 
            |
| 54 | 
                + lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True)  | 
            |
| 55 | 
                + login_ip = models.CharField(_(u'login_ip'), max_length=255, blank=True, null=True, help_text=_(u'登录IP'))  | 
            |
| 56 | 
                + login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS)  | 
            |
| 57 | 
                +  | 
            |
| 58 | 
                + class Meta:  | 
            |
| 59 | 
                + verbose_name = _(u'lensmanloginloginfo')  | 
            |
| 60 | 
                + verbose_name_plural = _(u'lensmanloginloginfo')  | 
            |
| 61 | 
                +  | 
            |
| 62 | 
                + def __unicode__(self):  | 
            |
| 63 | 
                + return unicode(self.pk)  | 
            |
| 64 | 
                +  | 
            |
| 65 | 
                +  | 
            |
| 66 | 
                +class UserInfo(CreateUpdateMixin):  | 
            |
| 67 | 
                + UNVERIFIED = 0  | 
            |
| 68 | 
                + ACTIVATED = 1  | 
            |
| 69 | 
                + DISABLED = 2  | 
            |
| 70 | 
                + DELETED = 3  | 
            |
| 71 | 
                +  | 
            |
| 72 | 
                + USER_STATUS = (  | 
            |
| 73 | 
                + (UNVERIFIED, u'未验证'),  | 
            |
| 74 | 
                + (ACTIVATED, u'已激活'),  | 
            |
| 75 | 
                + (DISABLED, u'已禁用'),  | 
            |
| 76 | 
                + (DELETED, u'已删除'),  | 
            |
| 77 | 
                + )  | 
            |
| 78 | 
                +  | 
            |
| 79 | 
                + MALE = 0  | 
            |
| 80 | 
                + FEMALE = 1  | 
            |
| 81 | 
                +  | 
            |
| 82 | 
                + SEX_TYPE = (  | 
            |
| 83 | 
                + (MALE, u'男'),  | 
            |
| 84 | 
                + (FEMALE, u'女'),  | 
            |
| 85 | 
                + )  | 
            |
| 86 | 
                +  | 
            |
| 87 | 
                + user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True, unique=True)  | 
            |
| 88 | 
                +  | 
            |
| 89 | 
                + username = models.CharField(_(u'username'), max_length=255, blank=True, null=True, help_text=u'用户用户名', db_index=True, unique=True)  | 
            |
| 90 | 
                + password = models.CharField(_(u'password'), max_length=255, blank=True, null=True, help_text=u'用户密码')  | 
            |
| 91 | 
                +  | 
            |
| 92 | 
                + name = models.CharField(_(u'name'), max_length=255, blank=True, null=True, help_text=u'用户姓名')  | 
            |
| 93 | 
                + sex = models.IntegerField(_(u'sex'), choices=SEX_TYPE, default=MALE, help_text=u'用户性别')  | 
            |
| 94 | 
                + phone = models.CharField(_(u'phone'), max_length=255, blank=True, null=True, help_text=u'用户电话', db_index=True, unique=True)  | 
            |
| 95 | 
                + location = models.CharField(_(u'location'), max_length=255, blank=True, null=True, help_text=u'用户地址')  | 
            |
| 96 | 
                +  | 
            |
| 97 | 
                + user_status = models.IntegerField(_(u'user_status'), choices=USER_STATUS, default=UNVERIFIED)  | 
            |
| 98 | 
                +  | 
            |
| 99 | 
                + signup_ip = models.CharField(_(u'signup_ip'), max_length=255, blank=True, null=True, help_text=_(u'注册IP'))  | 
            |
| 100 | 
                + login_ip = models.CharField(_(u'login_ip'), max_length=255, blank=True, null=True, help_text=_(u'登录IP'))  | 
            |
| 101 | 
                + login_at = models.DateTimeField(_(u'login_at'), blank=True, null=True, help_text=_(u'登录时间'))  | 
            |
| 102 | 
                +  | 
            |
| 103 | 
                + class Meta:  | 
            |
| 104 | 
                + verbose_name = _(u'userinfo')  | 
            |
| 105 | 
                + verbose_name_plural = _(u'userinfo')  | 
            |
| 106 | 
                +  | 
            |
| 107 | 
                + def __unicode__(self):  | 
            |
| 108 | 
                + return unicode(self.pk)  | 
            |
| 109 | 
                +  | 
            |
| 110 | 
                + def _data(self):  | 
            |
| 111 | 
                +        return {
               | 
            |
| 112 | 
                + 'user_id': self.user_id,  | 
            |
| 113 | 
                + 'username': self.username,  | 
            |
| 114 | 
                + }  | 
            |
| 115 | 
                +  | 
            |
| 116 | 
                + data = property(_data)  | 
            |
| 117 | 
                +  | 
            |
| 118 | 
                +  | 
            |
| 119 | 
                +class UserLoginLogInfo(CreateUpdateMixin):  | 
            |
| 120 | 
                + SUCCESS = 0  | 
            |
| 121 | 
                + PWD_ERROR = 1  | 
            |
| 122 | 
                + OTHER = 2  | 
            |
| 123 | 
                +  | 
            |
| 124 | 
                + LOGIN_RESULT = (  | 
            |
| 125 | 
                + (SUCCESS, u'登录成功'),  | 
            |
| 126 | 
                + (PWD_ERROR, u'密码错误'),  | 
            |
| 127 | 
                + (OTHER, u'其他'),  | 
            |
| 128 | 
                + )  | 
            |
| 129 | 
                +  | 
            |
| 130 | 
                + user_id = models.CharField(_(u'user_id'), max_length=255, blank=True, null=True, help_text=u'用户唯一标识', db_index=True)  | 
            |
| 131 | 
                + login_ip = models.CharField(_(u'login_ip'), max_length=255, blank=True, null=True, help_text=_(u'登录IP'))  | 
            |
| 132 | 
                + login_result = models.IntegerField(_(u'login_result'), choices=LOGIN_RESULT, default=SUCCESS)  | 
            |
| 133 | 
                +  | 
            |
| 134 | 
                + class Meta:  | 
            |
| 135 | 
                + verbose_name = _(u'userloginloginfo')  | 
            |
| 136 | 
                + verbose_name_plural = _(u'userloginloginfo')  | 
            |
| 137 | 
                +  | 
            |
| 138 | 
                + def __unicode__(self):  | 
            |
| 139 | 
                + return unicode(self.pk)  | 
            
                @@ -3,7 +3,7 @@  | 
            ||
| 3 | 3 | 
                from django.contrib.auth.models import User, Group  | 
            
| 4 | 4 | 
                from rest_framework import serializers  | 
            
| 5 | 5 | 
                 | 
            
| 6 | 
                -from account.models import LensmanInfo  | 
            |
| 6 | 
                +from account.models import LensmanInfo, UserInfo  | 
            |
| 7 | 7 | 
                 | 
            
| 8 | 8 | 
                 | 
            
| 9 | 9 | 
                class UserSerializer(serializers.HyperlinkedModelSerializer):  | 
            
                @@ -22,3 +22,9 @@ class LensmanInfoSerializer(serializers.HyperlinkedModelSerializer):  | 
            ||
| 22 | 22 | 
                class Meta:  | 
            
| 23 | 23 | 
                model = LensmanInfo  | 
            
| 24 | 24 | 
                         fields = ('lensman_id', 'name', 'sex', 'phone', 'location', 'proportion', 'created_at')
               | 
            
| 25 | 
                +  | 
            |
| 26 | 
                +  | 
            |
| 27 | 
                +class UserInfoSerializer(serializers.HyperlinkedModelSerializer):  | 
            |
| 28 | 
                + class Meta:  | 
            |
| 29 | 
                + model = UserInfo  | 
            |
| 30 | 
                +        fields = ('user_id', 'name', 'sex', 'phone', 'location', 'user_status', 'created_at')
               | 
            
                @@ -1,17 +1,22 @@  | 
            ||
| 1 | 1 | 
                # -*- coding: utf-8 -*-  | 
            
| 2 | 2 | 
                 | 
            
| 3 | 
                -from django.contrib.auth.hashers import check_password  | 
            |
| 3 | 
                +from django.contrib.auth.hashers import make_password, check_password  | 
            |
| 4 | 4 | 
                from django.contrib.auth.models import User, Group  | 
            
| 5 | 5 | 
                from django.http import JsonResponse  | 
            
| 6 | 6 | 
                 | 
            
| 7 | 7 | 
                from rest_framework import viewsets  | 
            
| 8 | 8 | 
                 | 
            
| 9 | 
                -from account.models import LensmanInfo  | 
            |
| 10 | 
                -from account.serializers import UserSerializer, GroupSerializer, LensmanInfoSerializer  | 
            |
| 9 | 
                +from account.models import LensmanInfo, UserInfo, UserLoginLogInfo  | 
            |
| 10 | 
                +from account.serializers import UserSerializer, GroupSerializer, LensmanInfoSerializer, UserInfoSerializer  | 
            |
| 11 | 
                +  | 
            |
| 12 | 
                +from utils.ip_utils import ip_addr  | 
            |
| 13 | 
                +from utils.uuid_utils import curtailUUID  | 
            |
| 14 | 
                +  | 
            |
| 15 | 
                +from TimeConvert import TimeConvert as tc  | 
            |
| 11 | 16 | 
                 | 
            
| 12 | 17 | 
                 | 
            
| 13 | 18 | 
                # curl -X POST -F username=xxxxxxx -F password=xxxxxxx http://api.xfoto.com.cn/login  | 
            
| 14 | 
                -def user_login(request):  | 
            |
| 19 | 
                +def lesman_login_api(request):  | 
            |
| 15 | 20 | 
                     username = request.POST.get('username', '')
               | 
            
| 16 | 21 | 
                     password = request.POST.get('password', '')
               | 
            
| 17 | 22 | 
                 | 
            
                @@ -38,6 +43,84 @@ def user_login(request):  | 
            ||
| 38 | 43 | 
                })  | 
            
| 39 | 44 | 
                 | 
            
| 40 | 45 | 
                 | 
            
| 46 | 
                +def user_is_registered_api(request):  | 
            |
| 47 | 
                +    username = request.POST.get('username', '')
               | 
            |
| 48 | 
                +    return JsonResponse({
               | 
            |
| 49 | 
                + 'status': 200,  | 
            |
| 50 | 
                + 'message': '',  | 
            |
| 51 | 
                +        'data': {
               | 
            |
| 52 | 
                + 'registered': UserInfo.objects.filter(username=username).exists(),  | 
            |
| 53 | 
                + }  | 
            |
| 54 | 
                + })  | 
            |
| 55 | 
                +  | 
            |
| 56 | 
                +  | 
            |
| 57 | 
                +def user_signup_api(request):  | 
            |
| 58 | 
                +    username = request.POST.get('username', '')
               | 
            |
| 59 | 
                +    password = request.POST.get('password', '')
               | 
            |
| 60 | 
                +  | 
            |
| 61 | 
                + if UserInfo.objects.filter(username=username).exists():  | 
            |
| 62 | 
                +        return JsonResponse({
               | 
            |
| 63 | 
                + 'status': 4010,  | 
            |
| 64 | 
                + 'message': u'该用户名已注册',  | 
            |
| 65 | 
                + })  | 
            |
| 66 | 
                +  | 
            |
| 67 | 
                + user = UserInfo.objects.create(  | 
            |
| 68 | 
                + user_id=curtailUUID(UserInfo, 'user_id'),  | 
            |
| 69 | 
                + username=username,  | 
            |
| 70 | 
                + password=make_password(password, None, 'pbkdf2_sha256'),  | 
            |
| 71 | 
                + user_status=UserInfo.ACTIVATED,  | 
            |
| 72 | 
                + signup_ip=ip_addr(request),  | 
            |
| 73 | 
                + )  | 
            |
| 74 | 
                +  | 
            |
| 75 | 
                +    return JsonResponse({
               | 
            |
| 76 | 
                + 'status': 200,  | 
            |
| 77 | 
                + 'message': u'注册成功',  | 
            |
| 78 | 
                + 'data': user.data,  | 
            |
| 79 | 
                + })  | 
            |
| 80 | 
                +  | 
            |
| 81 | 
                +  | 
            |
| 82 | 
                +def user_login_api(request):  | 
            |
| 83 | 
                +    username = request.POST.get('username', '')
               | 
            |
| 84 | 
                +    password = request.POST.get('password', '')
               | 
            |
| 85 | 
                +  | 
            |
| 86 | 
                + try:  | 
            |
| 87 | 
                + user = UserInfo.objects.get(username=username)  | 
            |
| 88 | 
                + except UserInfo.DoesNotExist:  | 
            |
| 89 | 
                +        return JsonResponse({
               | 
            |
| 90 | 
                + 'status': 4011,  | 
            |
| 91 | 
                + 'message': u'用户不存在',  | 
            |
| 92 | 
                + })  | 
            |
| 93 | 
                +  | 
            |
| 94 | 
                + login_ip, login_at = ip_addr(request), tc.utc_datetime()  | 
            |
| 95 | 
                +  | 
            |
| 96 | 
                + if not check_password(password, user.password):  | 
            |
| 97 | 
                + UserLoginLogInfo.objects.create(  | 
            |
| 98 | 
                + user_id=user.user_id,  | 
            |
| 99 | 
                + login_ip=login_ip,  | 
            |
| 100 | 
                + login_result=UserLoginLogInfo.PWD_ERROR  | 
            |
| 101 | 
                + )  | 
            |
| 102 | 
                +        return JsonResponse({
               | 
            |
| 103 | 
                + 'status': 4012,  | 
            |
| 104 | 
                + 'message': u'用户密码错误',  | 
            |
| 105 | 
                + })  | 
            |
| 106 | 
                +  | 
            |
| 107 | 
                + UserLoginLogInfo.objects.create(  | 
            |
| 108 | 
                + user_id=user.user_id,  | 
            |
| 109 | 
                + login_ip=login_ip,  | 
            |
| 110 | 
                + login_result=UserLoginLogInfo.SUCCESS  | 
            |
| 111 | 
                + )  | 
            |
| 112 | 
                +  | 
            |
| 113 | 
                + user.login_ip = login_ip  | 
            |
| 114 | 
                + user.login_at = login_at  | 
            |
| 115 | 
                + user.save()  | 
            |
| 116 | 
                +  | 
            |
| 117 | 
                +    return JsonResponse({
               | 
            |
| 118 | 
                + 'status': 200,  | 
            |
| 119 | 
                + 'message': u'登录成功',  | 
            |
| 120 | 
                + 'data': user.data,  | 
            |
| 121 | 
                + })  | 
            |
| 122 | 
                +  | 
            |
| 123 | 
                +  | 
            |
| 41 | 124 | 
                class UserViewSet(viewsets.ModelViewSet):  | 
            
| 42 | 125 | 
                """  | 
            
| 43 | 126 | 
                API endpoint that allows users to be viewed or edited.  | 
            
                @@ -57,3 +140,8 @@ class GroupViewSet(viewsets.ModelViewSet):  | 
            ||
| 57 | 140 | 
                class LensmanInfoViewSet(viewsets.ModelViewSet):  | 
            
| 58 | 141 | 
                     queryset = LensmanInfo.objects.all().order_by('-created_at')
               | 
            
| 59 | 142 | 
                serializer_class = LensmanInfoSerializer  | 
            
| 143 | 
                +  | 
            |
| 144 | 
                +  | 
            |
| 145 | 
                +class UserInfoViewSet(viewsets.ModelViewSet):  | 
            |
| 146 | 
                +    queryset = UserInfo.objects.all().order_by('-created_at')
               | 
            |
| 147 | 
                + serializer_class = UserInfoSerializer  | 
            
                @@ -7,16 +7,19 @@ from photo import views as photo_views  | 
            ||
| 7 | 7 | 
                 | 
            
| 8 | 8 | 
                 | 
            
| 9 | 9 | 
                urlpatterns = [  | 
            
| 10 | 
                - url(r'^login$', account_views.user_login, name='user_login'),  | 
            |
| 10 | 
                + url(r'^login$', account_views.lesman_login_api, name='lesman_login_api'),  | 
            |
| 11 | 
                + url(r'^u/is_registered$', account_views.user_is_registered_api, name='user_is_registered_api'), # 用户是否已经注册  | 
            |
| 12 | 
                + url(r'^u/signup$', account_views.user_signup_api, name='user_signup_api'), # 用户注册  | 
            |
| 13 | 
                + url(r'^u/login$', account_views.user_login_api, name='user_login_api'), # 用户登录  | 
            |
| 11 | 14 | 
                ]  | 
            
| 12 | 15 | 
                 | 
            
| 13 | 16 | 
                urlpatterns += [  | 
            
| 14 | 
                - url(r'^uuid_init$', photo_views.uuid_init, name='uuid_init'),  | 
            |
| 15 | 
                - url(r'^uuid$', photo_views.uuid, name='uuid'),  | 
            |
| 16 | 
                - url(r'^photos/upload$', photo_views.upload_photo, name='upload_photo'),  | 
            |
| 17 | 
                + url(r'^uuid_init$', photo_views.uuid_init, name='uuid_init'), # 生成唯一标识  | 
            |
| 18 | 
                + url(r'^uuid$', photo_views.uuid, name='uuid'), # 获取唯一标识  | 
            |
| 19 | 
                + url(r'^photos/upload$', photo_views.upload_photo, name='upload_photo'), # 上传图片  | 
            |
| 17 | 20 | 
                ]  | 
            
| 18 | 21 | 
                 | 
            
| 19 | 22 | 
                urlpatterns += [  | 
            
| 20 | 
                - url(r'^s/(?P<session>\w+)$', photo_views.session_detail_api, name='session_detail_api'),  | 
            |
| 23 | 
                + url(r'^s/(?P<session>\w+)$', photo_views.session_detail_api, name='session_detail_api'), # Session 详情  | 
            |
| 21 | 24 | 
                url(r'^p/(?P<photo>\w+)$', photo_views.photo_standard_api, name='photo_standard_api'), # standard thumbnail, available for free  | 
            
| 22 | 25 | 
                ]  | 
            
                @@ -1,6 +1,10 @@  | 
            ||
| 1 | 1 | 
                1、用户信息 —— 400  | 
            
| 2 | 
                - 4000 —— 用户不存在  | 
            |
| 3 | 
                - 4001 —— 用户密码错误  | 
            |
| 2 | 
                + 4000 —— 摄影师不存在  | 
            |
| 3 | 
                + 4001 —— 摄影师密码错误  | 
            |
| 4 | 
                +  | 
            |
| 5 | 
                + 4010 —— 用户名已注册  | 
            |
| 6 | 
                + 4011 —— 用户名不存在  | 
            |
| 7 | 
                + 4012 —— 用户密码错误  | 
            |
| 4 | 8 | 
                 | 
            
| 5 | 9 | 
                2、照片上传 —— 401  | 
            
| 6 | 10 | 
                4010 —— 参数错误  | 
            
                @@ -1,3 +1,5 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 1 | 3 | 
                """pai2 URL Configuration  | 
            
| 2 | 4 | 
                 | 
            
| 3 | 5 | 
                The `urlpatterns` list routes URLs to views. For more information please see:  | 
            
                @@ -26,6 +28,7 @@ router = routers.DefaultRouter()  | 
            ||
| 26 | 28 | 
                # router.register(r'users', account_views.UserViewSet)  | 
            
| 27 | 29 | 
                # router.register(r'groups', account_views.GroupViewSet)  | 
            
| 28 | 30 | 
                router.register(r'lensmans', account_views.LensmanInfoViewSet)  | 
            
| 31 | 
                +router.register(r'users', account_views.UserInfoViewSet)  | 
            |
| 29 | 32 | 
                router.register(r'photos', photo_views.PhotoInfoViewSet)  | 
            
| 30 | 33 | 
                 | 
            
| 31 | 34 | 
                urlpatterns = [  | 
            
                @@ -34,7 +37,7 @@ urlpatterns = [  | 
            ||
| 34 | 37 | 
                 | 
            
| 35 | 38 | 
                urlpatterns += [  | 
            
| 36 | 39 | 
                     # url(r'^api/', include('api.urls', namespace='api')),
               | 
            
| 37 | 
                - url(r'^s/(?P<session>\w+)$', photo_views.session_detail, name='session_detail'),  | 
            |
| 40 | 
                + url(r'^s/(?P<session>\w+)$', photo_views.session_detail, name='session_detail'), # Session 详情  | 
            |
| 38 | 41 | 
                url(r'^p/(?P<photo>\w+)$', photo_views.photo_standard, name='photo_standard'), # standard thumbnail, available for free  | 
            
| 39 | 42 | 
                url(r'^m/(?P<photo>\w+)$', photo_views.photo_medium, name='photo_medium'), # medium/mobile version, without watermark, login or paid by others  | 
            
| 40 | 43 | 
                url(r'^l/(?P<photo>\w+)$', photo_views.photo_large, name='photo_large'), # large, might support server side panning later, login required  | 
            
                @@ -1,6 +1,5 @@  | 
            ||
| 1 | 1 | 
                # -*- coding: utf-8 -*-  | 
            
| 2 | 2 | 
                 | 
            
| 3 | 
                -  | 
            |
| 4 | 3 | 
                from django.conf import settings  | 
            
| 5 | 4 | 
                from django.conf.urls import include, url  | 
            
| 6 | 5 | 
                 | 
            
                @@ -1,7 +1,7 @@  | 
            ||
| 1 | 1 | 
                CodeConvert==2.0.3  | 
            
| 2 | 2 | 
                Django==1.8.4  | 
            
| 3 | 3 | 
                MySQL-python==1.2.5  | 
            
| 4 | 
                -TimeConvert==1.0.7  | 
            |
| 4 | 
                +TimeConvert==1.1.3  | 
            |
| 5 | 5 | 
                django-multidomain==1.1.4  | 
            
| 6 | 6 | 
                django-shortuuidfield==0.1.3  | 
            
| 7 | 7 | 
                djangorestframework==3.3.1  | 
            
                @@ -0,0 +1,5 @@  | 
            ||
| 1 | 
                +# -*- coding: utf-8 -*-  | 
            |
| 2 | 
                +  | 
            |
| 3 | 
                +  | 
            |
| 4 | 
                +def ip_addr(request):  | 
            |
| 5 | 
                + return request.META['HTTP_X_FORWARDED_FOR'] if 'HTTP_X_FORWARDED_FOR' in request.META else request.META['REMOTE_ADDR']  | 
            
                @@ -2,8 +2,6 @@  | 
            ||
| 2 | 2 | 
                 | 
            
| 3 | 3 | 
                from django.conf import settings  | 
            
| 4 | 4 | 
                 | 
            
| 5 | 
                -from photo.models import UUIDInfo  | 
            |
| 6 | 
                -  | 
            |
| 7 | 5 | 
                import shortuuid  | 
            
| 8 | 6 | 
                 | 
            
| 9 | 7 | 
                 |